#include "serial.h"

// 配置 GPIO
static void Serial_GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 使能GPIOA时钟

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;   // 设置GPIO模式为复用推挽输出
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;         // 设置引脚为PA9
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);            
}

// 配置 USART
static void Serial_USART_Config(void)
{
    USART_InitTypeDef USART_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); // 使能USART1时钟

    USART_InitStructure.USART_BaudRate = 9600;                                      // 设置波特率为9600
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 无硬件流控制
    USART_InitStructure.USART_Mode = USART_Mode_Tx;                                 // 设置为发送模式
    USART_InitStructure.USART_Parity = USART_Parity_No;                             // 无校验位
    USART_InitStructure.USART_StopBits = USART_StopBits_1;                          // 1位停止位
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;                     // 8位数据位
    USART_Init(USART1, &USART_InitStructure);                                       // 初始化USART1

    USART_Cmd(USART1, ENABLE); // 使能USART1
}

// 初始化串口
void Serial_Init(void)
{
    Serial_GPIO_Config();  // 配置GPIO
    Serial_USART_Config(); // 配置USART
}

// 发送一个字节
void Serial_SendByte(uint8_t byte)
{
    USART_SendData(USART1, byte);  // 发送数据
    while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); // 等待发送完成
}

void Serial_SendArray(uint8_t *arr, uint16_t len)
{
    uint16_t i;
    for (i = 0; i < len; i++) // 遍历数组，逐个发送元素
    {
        Serial_SendByte(arr[i]); // 调用Serial_SendByte函数发送数组元素
    }
}

void Serial_SendString(char *str)
{
    uint8_t i;
    for (i = 0; str[i] != '\0'; i++) // 遍历字符串，直到遇到空字符'\0'
    {
        Serial_SendByte(str[i]); // 调用Serial_SendByte函数发送字符串中的字符
    }
}

static uint32_t Serial_Pow(uint32_t x, uint32_t y)
{
    uint32_t result = 1;
    while (y--) // 循环y次，计算x的y次方
    {
        result *= x; // 累乘结果
    }
    return result; // 返回结果
}

void Serial_SendNumber(uint32_t num, uint8_t len)
{
    uint8_t i;
    for (i = 0; i < len; i++) // 遍历数字的每一位
    {
        Serial_SendByte(num / Serial_Pow(10, len - i - 1) % 10 + '0'); // 将数字转换为字符并发送
    }
}

int _write(int fd, char *pBuffer, int size)
{
    for (int i = 0; i < size; i++) // 遍历缓冲区
    {
        Serial_SendByte((uint8_t)pBuffer[i]);
    }
    return size; // 返回发送的字节数
}

void Serial_Print(char *format, ...)
{
    char str[100];
    va_list arg;
    va_start(arg, format);      // 初始化可变参数列表
    vsprintf(str, format, arg); // 将格式化字符串写入str
    va_end(arg);                // 结束可变参数列表的使用
    Serial_SendString(str);     // 调用Serial_SendString函数发送字符串
}
